#include "systemexaminition.h"

SystemExaminition::SystemExaminition()
{
}



SystemState SystemExaminition::getSystemState() const
{
    SystemState systemState;

    MemState mem;
    unsigned int allSize, useSize;
    allSize = 0;
    useSize = 0;

    systemState.memOccRate = getMemOccupy((MemState *)&mem);
    systemState.cpuOccRate = getCpuOccupy();
    systemState.hardDiskOccRate = getDiskState(&allSize, &useSize);


    return systemState;
}

/*******************************************
  功能：内存使用率
  参数：
  返回值：
  ******************************************/
int getMemOccupy(MemState *mem)
//int getMemOccupy(MEM_OCCUPY *mem)
{
#ifdef Q_OS_LINUX
    int memUse;
    FILE *fd;
//    int n;
    char buff[256];
    char name[20];
    MemState *m;
    m = mem;

    fd = fopen("/proc/meminfo", "r");

    //linux内存使用率的计算：
    //1，从OS来看，内存的使用率为total-free (因为buffer/cached是属于被用的)
    //2, 从应用程序来看，内存的使用率为toatl-free-buffers-cache　(因为buffer/cached是属于可用的，buffers/cached是为了提高
    //                                                      文件读取的性能，当应用程序要用到内存时，buffers/cached会很快被回收)
    fgets(buff, 256, fd);
    sscanf(buff, "%s %lu", name, &m->totalMem);
    fgets(buff, 256, fd);
    sscanf(buff, "%s %lu", name, &m->freeMem);
    fgets(buff, 256, fd);
    sscanf(buff, "%s %lu", name, &m->buffers);
    fgets(buff, 256, fd);
    sscanf(buff, "%s %lu", name, &m->cached);

    m->usedMem = m->totalMem - m->freeMem - m->buffers - m->cached;

    fclose(fd);
    memUse = (m->usedMem * 100) / m->totalMem;

    return (memUse);
#else
    return -1;
#endif
}

/*******************************************
  功能：cpu状态信息
  参数：
  返回值：
  ******************************************/
void getCpuState(CpuState *cpuState)
{
#ifdef Q_OS_LINUX
        FILE *fd;
//        int n;
        char buff[256];
        char name[20];
        CpuState *cpu;
        cpu = cpuState;
//        unsigned int test;

        fd = fopen("/proc/stat", "r");
        fgets(buff, sizeof(buff), fd);

        sscanf(buff, "%s %u %u %u %u %u %u %u %u %u", name, &cpu->user, &cpu->nice,
                        &cpu->system, &cpu->idle, &cpu->iowait, &cpu->irq, &cpu->softirq,
                        &cpu->stealstolen, &cpu->guest);
        fclose(fd);
#else
#endif
}

/*******************************************
  功能：cpu使用率
  参数：
  返回值：
  ******************************************/
int getCpuOccupy()
{
        CpuState first;
        CpuState second;
        unsigned long od, nd;
        unsigned long id, sd;
        unsigned long idle;
        unsigned long totalTime;
        int cpu_use = 0;

        getCpuState((CpuState *)&first);
        usleep(1000 * 200);
        getCpuState((CpuState *)&second);


        od = (unsigned long)(first.user + first.nice + first.system + first.idle + first.iowait
                        + first.irq + first.softirq + first.stealstolen + first.guest);
        nd = (unsigned long)(second.user + second.nice + second.system + second.idle + second.iowait
                        + second.irq + second.softirq + second.stealstolen + second.guest);

        id = (unsigned long)(second.user - first.user);
        sd = (unsigned long)(second.system - first.system);
        idle = (unsigned long)(second.idle - first.idle);

        totalTime = nd - od;
        while(totalTime == 0 || (totalTime == idle))
        {

            getCpuState((CpuState *)&first);
            usleep(1000 * 200);
            getCpuState((CpuState *)&second);


            od = (unsigned long)(first.user + first.nice + first.system + first.idle + first.iowait
                            + first.irq + first.softirq + first.stealstolen + first.guest);
            nd = (unsigned long)(second.user + second.nice + second.system + second.idle + second.iowait
                            + second.irq + second.softirq + second.stealstolen + second.guest);

            idle = (unsigned long)(second.idle - first.idle);
            totalTime = nd - od;
        }

        cpu_use = (int) (((totalTime - idle) * 100) / (totalTime));
//        qDebug() << "cpu_use===>" << cpu_use << totalTime - idle << totalTime;
        return cpu_use;
}

/*******************************************
  功能：硬盘状态
  参数：
  返回值：
  ******************************************/
int getDiskState(unsigned int *allSize, unsigned int *useSize)
{
#ifdef Q_OS_LINUX
        unsigned int freeSize = 0;
        FILE *fd;
        int diskUse;

        fd = fopen("/etc/mtab", "rb");

        if (NULL == fd)
        {
                return 0;
        }

        while(1)
        {
                struct mntent *mt = getmntent(fd);
                if (NULL == mt)
                {
                        break;
                }

                if (NULL != strstr(mt->mnt_fsname, "/dev/"))
                {
                        struct statfs buf;
                        statfs(mt->mnt_dir, &buf);
                        *allSize += (buf.f_bsize / 1024 * buf.f_blocks);
                        freeSize += (buf.f_bsize / 1024 * buf.f_bavail);
                }
        }
        *useSize = *allSize - freeSize;
        *useSize = *useSize / 1024;
        *allSize = *allSize / 1024;
        fclose(fd);
        diskUse = 100 * (*useSize) / (*allSize);
        return diskUse;
#else
    return -1;
#endif
}
